﻿/*****************************************************************//**
 * @file   FITKAbstractVAOneXMLHelper.h
 * @brief  VAOneXML处理助手类
 * 
 * @author TanDongYang
 * @date   2024-11-08
 *********************************************************************/

#ifndef FITKABSTRACTVAONEXMLHELPER_H
#define FITKABSTRACTVAONEXMLHELPER_H

#include "FITKVAOneXMLIOAPI.h"
#include "FITK_Kernel/FITKAdaptor/FITKAbstractIOAdaptor.h"
#include "FITK_Kernel/FITKAdaptor/FITKIOAdaptorFactory.h"
#include <QDebug>

namespace Acoustics
{
    class FITKAbstractSEASubSys;
    class FITKAcousticsFESubSysManager;
    class FITKAcousticsSEASubSysManager;
    class FITKAcousticsSpectraManager;
    class FITKAcousticsMaterialManager;
    class FITKAcousticsLoadManager;
    class FITKJunctionManager;
    class FITKAcousticsPhysicsPropManager;
    class FITKAcousticsFESubSysElementList;
    class FITKAcousticsFEModel;
    class FITKAcousticsSEAModel;
    class FITKAcousticsPhysics;
    class FITKAcousticsDiscModel;
    class FITKAcousticsDiscNodeList;
    class FITKSEAFaceManager;
    class FITKAcousticsFEFaceManager;
    class FITKAcousticsNCTManager;
}

namespace rapidxml
{
    template<class Ch>
    class xml_node;
    enum node_type;
}

namespace IO {
    /**
     * @brief   VAOneXML处理助手类
     * @author  TanDongYang (tandongyang@diso.cn)
     * @date    2024-11-08 
     */
    class FITKVAOneXMLIOAPI FITKAbstractVAOneXMLHelper : public Adaptor::FITKAbstractIOAdaptor
    {
    public:
        /**
         * @brief   构造函数
         * @author  TanDongYang (tandongyang@diso.cn)
         * @date    2024-11-08 
         */
        explicit FITKAbstractVAOneXMLHelper() = default;

        /**
         * @brief   析构函数
         * @author  TanDongYang (tandongyang@diso.cn)
         * @date    2024-11-08 
         */
        virtual ~FITKAbstractVAOneXMLHelper() = default;


    protected:

        /**
         * @brief 根据材料名称获取材料id
         * @param[i] name 材料名称
         * @return int 材料id 无则返回-1
         * @author liuzhiyuan@diso.com
         * @date 2024-10-18
         */
        int getMaterialObjectIdByName(QString name);
        /**
         * @brief 根据材料ID获取材料名称
         * @param[i] id 材料id
         * @return QString 材料名称 无则返回空
         * @author liuzhiyuan@diso.com
         * @date 2024-10-18
         */
        QString getMaterialObjectNameById(int id);
        /**
         * @brief 根据频谱名称获取频谱id
         * @param[i] name 频谱名称
         * @return int 频谱id 无则返回-1
         * @author liuzhiyuan@diso.com
         * @date 2024-10-18
         */
        int getSpectraObjectIdByName(QString name);
        /**
         * @brief 根据频谱ID获取频谱名称
         * @param[i] id 频谱id
         * @return int 频谱名称 无则返回空
         * @author liuzhiyuan@diso.com
         * @date 2024-10-18
         */
        QString getSpectraObjectNameByID(int id);
        /**
         * @brief 根据声包名称获取声包id
         * @param[i] name 声包名称
         * @return int 声包id 无则返回-1
         * @author liuzhiyuan@diso.com
         * @date 2024-10-18
         */
        int getAcousticsObjectIdByName(QString name);

        /**
         * @brief 根据名称获取物理属性id
         * @param name 属性名
         * @return 属性id 无效返回-1
         * @author lixiaolong (lixiaolong@diso.cn)
         * @date 2024-11-13
         */
        int getPhyPropertyId(QString name);

        /**
         * @brief 根据id获取物理属性名字
         * @param 属性id
         * @return  name 属性名 无效返回""
         * @author lixiaolong (lixiaolong@diso.cn)
         * @date 2024-11-13
         */
        QString getPhyPropertyName(int id);

        /**
         * @brief getFaceObjId   获取face objid(faceid转objid)
         * @param faceId[i]      face id(xml文件里的id)
         * @return               objid -1 无效值
         * @author  lixiaolong (lixiaolong@diso.cn)
         * @date    2024-11-8
         */
        int getFaceObjId(int faceId);

        /**
         * @brief getNCTID 根据名字获声学包id
         * @param name 名字
         * @return  id
         * @author  lixiaolong (lixiaolong@diso.cn)
         * @date    2024-11-7
         */
        int getNCTID(QString name);

        /**
         * @brief getNCTName 根据声学包id获取名字
         * @param id  id
         * @return  名字
         * @author  lixiaolong (lixiaolong@diso.cn)
         * @date    2024-11-7
         */
        QString getNCTName(int id);

        /**
         * @brief getModalDensityId   获取模态密度id
         * @param name[i]             名字
         * @return            数据id -1 无效值
         * @author  lixiaolong (lixiaolong@diso.cn)
         * @date    2024-11-8
         */
        int getModalDensityId(QString name);

        /**
         * @brief getModalDensityName   获取模态密度名
         * @param id[i] 模态密度id
         * @return   模态密度名
         * @author  lixiaolong (lixiaolong@diso.cn)
         * @date    2024-11-8
         */
        QString getModalDensityName(int id);

        /**
         * @brief getDampingId   获取损耗因子谱id
         * @param name[i]             名字
         * @return            数据id -1 无效值
         * @author  lixiaolong (lixiaolong@diso.cn)
         * @date    2024-11-8
         */
        int getDampingId(QString name);

        /**
         * @brief getDampingName   获取损耗因子谱名
         * @param id[i] 损耗因子谱id
         * @return   损耗因子谱名
         * @author  lixiaolong (lixiaolong@diso.cn)
         * @date    2024-11-8
         */
        QString getDampingName(int id);

        /**
         * @brief strToBool   字符串转bool
         * @param str[i]      待转换字符串
         * @return            true/false
         * @author  lixiaolong (lixiaolong@diso.cn)
         * @date    2024-11-8
         */
        bool strToBool(QString str);

        /**
         * @brief strToBool   bool转字符串
         * @param flag[i]     待转换bool值
         * @return            "true"/"false"
         * @author  lixiaolong (lixiaolong@diso.cn)
         * @date    2024-11-8
         */
        QString boolToStr(bool flag);

    protected:
        /**
         * @brief 通过face_id获取板对象
         * @param faceID[i]     face_id
         * @return            "true"/"false"
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-13
         */
        Acoustics::FITKAbstractSEASubSys* getShellObjByXMLFace_id(int faceID);

        /**
         * @brief 通过板子系统id获取face_id
         * @param shellSysId[i]     板子系统id
         * @return            int
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-13
         */
        int getFaceIdByShellSysId(int shellSysId);

        /**
         * @brief 获取FE子系统管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-15
         */
        Acoustics::FITKAcousticsFESubSysManager* getFESubSystemManager();

        /**
         * @brief 获取频谱管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-15
         */
        Acoustics::FITKAcousticsSpectraManager* getSpectraManager();

        /**
         * @brief 获取材料管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-16
         */
        Acoustics::FITKAcousticsMaterialManager* getMaterialManager();

        /**
         * @brief 获取物理属性管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-16
         */
        Acoustics::FITKAcousticsPhysicsPropManager* getPhysicalPropertiesManager();

        /**
         * @brief 获取FE子系统单元列表
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-16
         */
        Acoustics::FITKAcousticsFESubSysElementList* getFESubSysElementList();

        /**
         * @brief 获取FE模型
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-16
         */
        Acoustics::FITKAcousticsFEModel* getFEModel();

        /**
         * @brief 获取SEA模型
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-17
         */
        Acoustics::FITKAcousticsSEAModel* getSEAModel();

        /**
         * @brief 获取声学物理属性管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-17
         */
        Acoustics::FITKAcousticsPhysics* getPhysics();

        /**
         * @brief 获取声学离散模型
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-17
         */
        Acoustics::FITKAcousticsDiscModel* getDiscModel();

        /**
         * @brief 获取载荷管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-17
         */
        Acoustics::FITKAcousticsLoadManager* getLoadManager();

        /**
         * @brief 获取交点管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-17
         */
        Acoustics::FITKJunctionManager* getJunctionManager();

        /**
         * @brief 获取SEA子系统管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-17
         */
        Acoustics::FITKAcousticsSEASubSysManager* getSEASubSysManager();

        /**
         * @brief 通过父节点创建子节点
         * @param  parentNode父节点，childNodeName子节点名称，type节点类型
         * @return  childNode子节点
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-21
         */
        rapidxml::xml_node<char>* createChildNode(rapidxml::xml_node<char>* parentNode, const char* childNodeName, rapidxml::node_type type);

        /**
         * @brief 通过一级节点创建三级节点（仅限二级节点无属性）
         * @param  primaryNode一级节点，secondLevelName二级节点名称，thirdLevelName三级节点名称，type节点类型
         * @return  thirdLevelNode三级节点
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-01-21
         */
        rapidxml::xml_node<char>* createThirdLevelNode(rapidxml::xml_node<char>* primaryNode, const char* secondLevelName, const char* thirdLevelName, rapidxml::node_type type);
        
        /**
         * @brief 获取离散节点列表
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-02-06
         */
        Acoustics::FITKAcousticsDiscNodeList* getDiscNodeList();

        /**
         * @brief 获取SEA面管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-02-06
         */
        Acoustics::FITKSEAFaceManager* getSEAFacesManager();

        /**
         * @brief 获取FE面管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-02-27
         */
        Acoustics::FITKAcousticsFEFaceManager* getFEFaceManager();

        /**
         * @brief 获取声学包管理器
         * @param  none
         * @return   manager
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-02-10
         */
        Acoustics::FITKAcousticsNCTManager* getNoiseControlTreatmentsManager();

        /**
         * @brief   双精度浮点数格式转换
         * @param   number 双精度浮点数，precision 精度
         * @return  QString
         * @author  lilongyuan (lilongyuan@diso.cn)
         * @date    2025-02-17
         */
        QString doubleFormatConversion(double number, int precision);
    protected:
        /**
         * @brief     读取XML节点适配器模板
         * @param[i]  node 节点，nodeName 节点名称，adaptor 适配器，adaptorName 适配器名称
         * @return    是否执行成功
         * @author    lilongyuan (lilongyuan@diso.cn)
         * @date      2025-02-10
         */
        template <typename T>
        bool readXMLNodeAdaptor(rapidxml::xml_node<char>* node, QString nodeName, T* adaptor,QString adaptorName)
        {
            // node、nodeName和adaptorName不能为空
            if (node == nullptr || nodeName.isEmpty() || adaptorName.isEmpty()) return false;

            // 开始读取节点数据
            qDebug() << "Start read" << QString("%1.").arg(nodeName);

            // 获取读取适配器
            adaptor = FITKIOADAPTORFACTORY->createT<T>("VAOneXML", adaptorName);
            if (!adaptor) return false;

            // 设置节点
            adaptor->setNode(node);

            // 适配器读取操作
            bool ok = adaptor->adaptR();
            if (!ok) qDebug() << "Read" << QString("%1").arg(nodeName) << "failed.";

            // 删除适配器对象
            delete adaptor;

            return ok;
        }
        /**
         * @brief     写出XML节点适配器模板
         * @param[i]  node 节点，nodeName 节点名称，adaptor 适配器，adaptorName 适配器名称
         * @return    是否执行成功
         * @author    lilongyuan (lilongyuan@diso.cn)
         * @date      2025-02-11
         */
        template <typename T>
        bool writeXMLNodeAdaptor(rapidxml::xml_node<char>* node, QString nodeName, T* adaptor, QString adaptorName)
        {
            // node、nodeName和adaptorName不能为空
            if (node == nullptr || nodeName.isEmpty() || adaptorName.isEmpty()) return false;

            // 开始写出节点数据
            qDebug() << "Start write" << QString("%1.").arg(nodeName);

            // 获取写出适配器
            adaptor = FITKIOADAPTORFACTORY->createT<T>("VAOneXML", adaptorName);
            if (!adaptor) return false;

            // 设置节点
            adaptor->setNode(node);

            // 适配器写出操作
            bool ok = adaptor->adaptW();
            if (!ok) qDebug() << "Write" << QString("%1").arg(nodeName) << "failed.";

            // 删除适配器对象
            delete adaptor;

            return ok;
        }
    };
}

#endif // FITKABSTRACTVAONEXMLHELPER_H
